As computers and the computer software executing on computers becomes more complex and powerful, performance analysis techniques have increased in importance for optimizing the performance and reliability of computer software. One technique that has been found to be useful in connection with analyzing the performance of computer software is profiling.
With profiling, a tool commonly referred to as a profiler is used to capture events and other statistical information about program code being profiled. For example, a profiler may be used to capture information regarding memory and other resource usage for the purpose of identifying potential memory leaks, garbage collection problems, or other circumstances that may lead to excessive consumption of system resources. As another example, a profiler may be used to capture information such as the time spent in various routines, the number of instances created for certain object classes, and the state of a call stack for the purpose of identifying particular sections of program code that perform sub-optimally. Profiling may be performed by instrumenting program code prior to compilation, or alternatively, a runtime environment may support data collection capabilities to capture relevant profiling information for uninstrumented program code.
Profiling may be utilized in a number of computer environments. For example, profiling may be utilized for profiling program code executing within a JAVA virtual machine (JVM). The JAVA architecture, for example, includes a profiling API that extracts profiling information for program code executing in a JVM.
The profile extraction functionality in a JVM, however, has been found to be limited in certain circumstances, and in particular, in connection with profiling JAVA applications deployed to a J2EE application server running in a JVM. An application server generally provides a runtime environment for the applications that are deployed to the application server, and JAVA applications that execute in a J2EE application server all run in a common process with the application server. As a result, in many conventional JVM-based profilers, the collection of profiling information for one of the applications executing in an application server requires that profiling information also be collected for the other applications executing in the application server, as well as the application server itself, because such profilers are generally incapable of distinguishing between different applications executing in the same process.
Collecting profile information for the application server and other applications in connection with collecting profile information for an application of interest, however, presents a number of problems. First, profiling the application server and the other applications typically causes the application server to run slower. It is often desirable for the application server to run as fast as possible when profiling to recreate the real world environment for the application as much as possible. Second, the profile information collected from the application server and the other applications often obscures the information for the application of interest. An application server may have hundreds or thousands of classes, so even if a developer was profiling a small application containing 20 or so classes, the developer would have to sift through profiling information for every class in the application server even though he or she was probably only interested in the 20 or so classes that comprise the application of interest.
Some conventional profilers attempt to address this problem by using package and class name filtering to restrict the collection of profile information to only certain classes executing in a JVM. For example, if a developer wanted to profile an application named “App A” they could enter the package filter “com.customer.AppA.*”, whereby the profiler would collect profile information only for classes that were part of this package.
While package and class name filtering is sufficient in some circumstances, there are several problems with a filter-based approach that limits its usefulness in other circumstances. First, filtering relies on a developer to use proper package naming during development. Any departure from proper naming and packaging conventions by a developer may make it difficult to properly profile an application at a later date. Second, filtering requires a familiarity with the naming conventions used for an application. As a result, testers or administrators not familiar with an application may find it difficult to configure a profiler to profile an application of interest. Third, some applications may have hundreds or thousands of classes distributed through several packages. As a result, defining filters for all of the packages in such an application would be extremely difficult using a filter-based approach.
Therefore, a significant need continues to exist in the art for an improved manner for profiling applications executing in an application server or like runtime environment.